import {
  Component, OnInit, ChangeDetectionStrategy,
  Input, Output, EventEmitter, SimpleChanges, OnChanges, OnDestroy, ViewChild
} from '@angular/core';

import { NzFormatEmitEvent, NzTreeNode, NzTreeComponent } from 'ng-zorro-antd';
import { NzContextMenuService, NzDropdownMenuComponent, } from 'ng-zorro-antd/dropdown';

import { CoreMessageService } from '../../core/services/core-message.service';

@Component({
  selector: 'app-map-tree',
  templateUrl: './map-tree.component.html',
  styleUrls: ['./map-tree.component.scss'],
})
export class MapTreeComponent implements OnInit, OnChanges, OnDestroy {
  activedNode: NzTreeNode;
  @ViewChild('nzTreeComponent', { static: false }) nzTreeComponent: NzTreeComponent;
  @Input() nodes = [];
  @Output() getDefaultKeys = new EventEmitter<Array<string>>(); // 默认选中节点
  @Output() selectKeys = new EventEmitter<Array<string>>(); //   选中keys
  @Output() removeKeys = new EventEmitter<Array<string>>(); //   取消选中keys
  @Output() treeDestroy = new EventEmitter<Array<string>>();
  totalLayer: number = 0;
  searchValue = null;
  defaultCheckedKeys = [];  // 默认选中的key -- 内容回更改
  defaultCheckedKeysBack = [];  // 默认选中的key 备份-- 内容不会更改
  sub;
  subscription = [];
  constructor(private nzContextMenuService: NzContextMenuService, private coreMessageService: CoreMessageService) { }

  ngOnInit() {
    // 未使用
    this.coreMessageService.currentLayerStatus.subscribe((layerinfo: any) => {
      const arr = layerinfo.rlayer;
      // 测试开始
      let obj;
      if (layerinfo.active) {
        arr.forEach(element => {
          obj = {
            isChecked: 'checked',
            key: element
          };
          this.defaultCheckedKeys.push(element);
          this.leafNodeInteraction(obj);
        });
      } else {
        arr.forEach(element => {
          obj = { key: element };
          this.leafNodeInteraction(obj);
          // 或者直接使用
          // this.removeKeys.emit([element]);
        });
      }

    });

    this.subscription.push(
      postal.channel('MAP_TREE_CHANNEL').subscribe('nodeinfo', layerinfo => {
        const arr = layerinfo.rlayer;
        if (!Array.isArray(arr)) {
          return;
        }
        let obj;
        if (layerinfo.active) {
          // 图层加载成功！
          arr.forEach(element => {
            obj = {
              isChecked: 'checked',
              key: element
            };
            // 图层加载成功！
            this.leafNodeInteraction(obj);
            // 非勾选状态下进行勾选，否则不再执行勾选操作！！
            const lyrNode = this.nzTreeComponent.getTreeNodeByKey(element)
            if (lyrNode && !lyrNode.isChecked) {
              // 设置图层树勾选状态为true
              lyrNode.isChecked = true;
            }
          });
        } else {
          arr.forEach(element => {
            obj = { key: element };
            this.leafNodeInteraction(obj);
            // 设置勾选状态为false
            const lyrNode = this.nzTreeComponent.getTreeNodeByKey(element)
            if (lyrNode) {
              lyrNode.isChecked = false;
            }
            // 或者直接使用
            // this.removeKeys.emit([element]);
          });
        }
      })
    );
  }

  checkChange(e) {
    // 传递给我的数据，有用的一个是：e.node.isleaf,用于判断是否是叶子节点，
    // 一个是ischecked：叶子节点的函数处理里用了
    // 一个是node.key、node.children、node.checked
    if (e.node.isLeaf) {
      this.leafNodeInteraction(e.node);
    } else {
      this.nonleafNodeInteraction(e.node);
    }
  }
  // 叶子节点控制
  leafNodeInteraction(node) {
    if (node.isChecked) {
      // 加载图层&选中图层
      this.selectKeys.emit([node.key]);
    } else {
      // 移除图层
      this.removeKeys.emit([node.key]);
    }
  }
  // 非叶子节点控制
  // 要向下递归查询所有叶子节点
  nonleafNodeInteraction(node) {
    // 和叶子节点唯一不同是获取了一下key数组，然后再触发的添加事件！（我们可以提前处理好，比如现在的代码内容）
    const childsKes = this.getAllChilds(node, 0);
    if (node.isChecked) {
      //  选中图层
      this.selectKeys.emit(childsKes);
    } else {
      // 移除图层
      this.removeKeys.emit(childsKes);
    }
  }
  /**
   *   查询所有子节点key,
   *   tag : 只能传入 0(所有子节点keys) 或 1(选中的子节点keys) 或 2(未选中的所有子节点keys) ;
   */
  private getAllChilds(node, tag: 0 | 1 | 2) {
    const result = [];
    // tslint:disable-next-line:no-shadowed-variable
    const findChilds = (node) => {
      if (node.isLeaf) {
        if (tag === 0) {
          result.push(node.key);
        }
        if (tag === 1 && (node.checked || node.isChecked)) {
          result.push(node.key);
        }
        if (tag === 2 && !node.checked && !node.isChecked) {
          result.push(node.key);
        }
      } else {
        if (node.children) {
          node.children.forEach(cnode => {
            findChilds(cnode);
          });
        }
      }
    };
    if (Array.isArray(node)) {
      node.forEach(item => {
        findChilds(item);
      });
    } else {
      findChilds(node);
    }

    return result;
  }
  openFolder(data: NzTreeNode | Required<NzFormatEmitEvent>): void {
    // do something if u want
    if (data instanceof NzTreeNode) {
      data.isExpanded = !data.isExpanded;
    } else {
      const node = data.node;
      if (node) {
        node.isExpanded = !node.isExpanded;
      }
    }
  }
  searchValueChange(nodes) {
    let func = function forNodes(node, key) {
      if (node.key === key) {
        node.searched = true;
      } else {
        node.searched = false;
      }
      if (node.children) {
        for (let item of node.children) {
          func(item, key);
        }
      }
    };
    if (nodes && nodes.keys) {
      nodes.keys.forEach(key => {
        if (this.nodes instanceof Array) {
          this.nodes.forEach(tmpnode => {
            func(tmpnode, key);
          });
        }
      });
    }
  }
  activeNode(data: NzFormatEmitEvent): void {
    // this.activedNode = data.node!;
  }
  clearAllSelected() {
    // 首先置空搜索内容
    this.searchValue = null;
    // 遍历清空勾选的图层树内容
    const leafNodes = this.getAllChilds(this.nodes, 1);
    const tmpdefaultCheckedKeys = [];
    leafNodes.forEach(item => {
      this.defaultCheckedKeysBack.forEach(jtem => {
        if (item === jtem) {
          tmpdefaultCheckedKeys.push(item);
        }
      });
    });
    this.defaultCheckedKeys = [...tmpdefaultCheckedKeys];
    const removeNodes = leafNodes.filter(i => {
      return this.defaultCheckedKeys.indexOf(i) === -1;
    });

    this.removeKeys.emit(removeNodes);
  }
  contextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void {
    this.nzContextMenuService.create($event, menu);
  }
  selectDropdown(): void {
  }
  treeSearch(node) {
    // this.nodeSearch.emit(node);
    this.coreMessageService.messageAction(node.origin);
  }
  ngOnChanges(changes: SimpleChanges): void {
    const defaultsNodesKey: Array<string> = this.getAllChilds(this.nodes, 1);//获取所有选中的节点
    this.totalLayer = (this.getAllChilds(this.nodes, 0) || []).length;
    this.defaultCheckedKeys = defaultsNodesKey;
    this.defaultCheckedKeysBack = defaultsNodesKey;
    this.getDefaultKeys.emit(defaultsNodesKey);
  }
  ngOnDestroy(): void {
    const allSelectNodes = this.getAllChilds(this.nodes, 1);
    const filterNodes = allSelectNodes.filter(item => {
      return this.defaultCheckedKeys.indexOf(item) === -1;
    });
    this.treeDestroy.emit(filterNodes);
    // console
    // .log(this.getAllChilds(this.nodes[0],0,))
    this.subscription.forEach(element => {
      element.unsubscribe();
    });
  }

}
